#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <UIKit/UIApplication.h>

#import "framework/FWCommon.h"
#import "framework/FWColorIconView.h"

#import "PITodoListAccess.h"
#import "PITodoStatus.h"
#import "PITodoPreview.h"
#import "PIIntegration.h"
#import "PIContextObject.h"
#import "PITaskIntegration.h"
#import "PITask.h"


@implementation PITodoPreview

@synthesize parentKeys, detailPageID;


- (void)dealloc
{
    [parentKeys release];
    [detailPageID release];
    
    [super dealloc];
}


// ******************************************************************************************
#pragma mark -
#pragma mark Handling user input

- (BOOL)doneClicked:(FWApplication*)application sections:(NSArray*)sections
{
    return YES;
}

- (FWDetailListEntry*)flaggedEntryWithTitle:(NSString*)title icon:(NSString*)icon calendarIcon:(NSString*)calendartIcon flagged:(BOOL)flagged largeFlag:(BOOL)large application:(FWApplication*)application
{
    FWDetailListEntry* titleEntry = [FWDetailListEntry entryWithTitle:[PIIntegration stringForTitle:title
                                                                                           withIcon:icon
                                                                                    withProjectIcon:calendartIcon]];
    if (flagged) {
        if (large)
            titleEntry.icon = [UIImage imageWithContentsOfFile:[PIIntegration iconPathForLargeFlag:application]];
        else
            titleEntry.icon = [UIImage imageWithContentsOfFile:[PIIntegration iconPathForSmallFlag:application]];
    }
    
    return titleEntry;
}


// ******************************************************************************************
#pragma mark -
#pragma mark Accessing records from the database

static NSString* const kNotesPageDetail = @"-1";
static NSString* const kLinkPageLookup = @"-2";
static NSString* const kTagsPageLookup = @"-3";


- (NSString*)captionForListPage:(NSObject*)page forKey:(NSObject*)key displayDepth:(NSInteger)depth application:(FWApplication *)application
{
    NSBundle* bundle = [NSBundle bundleForClass:[self class]];
    
    if ([(NSString*)key isEqualToString:kNotesPageDetail])
        return localize(bundle, @"Detail/Notes");
    if ([(NSString*)key isEqualToString:kTagsPageLookup])
        return localize(bundle, @"Detail/Tags");
    
    PITask* element = (PITask*)[(NSArray*)page objectAtIndex:0];
    if (element.isChild)
         return localize(bundle, @"Detail/Child");
    else if (element.isParent)
         return localize(bundle, @"Detail/Parent");
    else
        return @"";
}

- (NSArray*)dataForTagsListPage:(NSObject*)page application:(FWApplication *)application
{
    PITask* task = [PITaskIntegration augmentedBasicTask:(PITask*)page application:application];
    
    NSMutableArray* tagEntries = [NSMutableArray arrayWithCapacity:task.tags.count];
    NSMutableArray* tags = [NSMutableArray arrayWithArray:task.tags];
    [tags sortUsingFunction:compareContextObjectNames context:nil];
    
    for (PIContextObject* tag in tags) {
        [tagEntries addObject:[FWDetailListEntry entryWithTitle:[PIIntegration stringForTitle:tag.name
                                                                                     withIcon:tag.icon
                                                                              withProjectIcon:nil]]];
    }
    
    return [NSArray arrayWithObject:[FWDetailListSection sectionForElements:tagEntries]];
}


- (NSArray*)dataForTaskListPage:(NSObject*)page application:(FWApplication *)application
{
    NSBundle* bundle = [NSBundle bundleForClass:[self class]];
    PITask* task = [PITaskIntegration augmentedBasicTask:(PITask*)page application:application];

    XLog(@"LI:PITodo: Displaying detail of task %@", task);

    FWDetailListEntry* titleRows = [[self flaggedEntryWithTitle:task.title
                                                           icon:task.icon
                                                   calendarIcon:nil
                                                        flagged:task.flagged
                                                      largeFlag:YES
                                                    application:application]
                                    withSize:[FWDetailListEntry fontSizeForTitle]];
    
    NSArray* titleSect = [NSArray arrayWithObjects:
                          titleRows,
                          nil];
    
    BOOL overdue = NO;
    UIColor* dateBG = [UIColor whiteColor];
    NSDate* startDate = task.startDate;
    NSDate* dueDate = task.dueDate;
    NSDate* dueTime = task.dueTime;
    
    if (!dueTime.isNull)
        dueDate = dueTime;
    
    if (!dueDate.isNull) {
        NSDate *now = [NSDate date];
        if ([dueDate isEarlierThanDate:now]) {
            overdue = YES;
            dateBG = [PIIntegration colorForOverdue:application];
        }
    }
    
    // Dates section
    NSMutableArray* datesSect = [NSMutableArray arrayWithCapacity:2];
    
    if (!startDate.isNull) {
        [datesSect addObject:
         [[FWDetailListEntry entryWithLocalisedTitle:@"Detail/Start"
                                               value:FWLocalDateStringForUTCDate(startDate, FWDateFormatterLongFormat, NO, bundle)
                                              bundle:bundle]
          withBackgroundColor:dateBG]];
#ifdef DEBUG
        [datesSect addObject:
         [[FWDetailListEntry entryWithTitle:@"Start Date*"
                                      value:[NSString stringWithFormat:@"%@", startDate]]
          withBackgroundColor:dateBG]];
#endif
    }
    
    if (!dueDate.isNull) {
        BOOL showTime = !dueTime.isNull;
        [datesSect addObject:
         [[FWDetailListEntry entryWithLocalisedTitle:@"Detail/Due"
                                               value:FWLocalDateStringForUTCDate(dueDate, FWDateFormatterLongFormat, showTime, bundle)
                                              bundle:bundle]
          withBackgroundColor:dateBG]];
#ifdef DEBUG
        [datesSect addObject:
         [[FWDetailListEntry entryWithTitle:@"Due Date*"
                                      value:[NSString stringWithFormat:@"%@", dueDate]]
          withBackgroundColor:dateBG]];
        [datesSect addObject:
         [[FWDetailListEntry entryWithTitle:@"Due Time*"
                                      value:[NSString stringWithFormat:@"%@", dueTime]]
          withBackgroundColor:dateBG]];
#endif
    }
    
    // Context section
    NSMutableArray* contextSect = [NSMutableArray arrayWithCapacity:3];
#ifdef DEBUG
    [contextSect addObject:
     [FWDetailListEntry entryWithTitle:@"Key"
                                 value:task.key]];
#endif
    
    if ([task.context length] > 0)
        [contextSect addObject:
         [FWDetailListEntry entryWithLocalisedTitle:@"Detail/Context"
                                              value:task.context
                                             bundle:bundle]];
    
    if ([task.project length] > 0) {
        NSString* label = (task.priority.length == 0) && ([PIIntegration taskMode:application] == PITaskModeGTD) ? @"Detail/Project" : @"Detail/Folder";
        [contextSect addObject:
         [FWDetailListEntry entryWithLocalisedTitle:label
                                              value:task.project
                                             bundle:bundle]];
    }
    
    if (task.tags) {
        FWDetailListEntry* entry = [FWDetailListEntry entryWithLocalisedTitle:@"Detail/Tags"
                                                                        value:[task.tags piContextObjectString]
                                                                       bundle:bundle];
    
        if (task.tags.count > 1)
            [entry withLinkType:kTagsPageLookup];
    
        [contextSect addObject:entry];
    }
    
    
//    if (cCalendarID == -2)
//        calendar = localize(bundle, @"Detail/Internal Task Calendar");
    if ([task.calendar length] > 0)
        [contextSect addObject:
         [FWDetailListEntry entryWithLocalisedTitle:@"Detail/Calendar/PI"
                                              value:[PIIntegration stringForTitle:task.calendar
                                                                         withIcon:task.calendarIcon
                                                                  withProjectIcon:nil]
                                             bundle:bundle]];
    
    // Progress section
    NSMutableArray* progressSect = [NSMutableArray arrayWithCapacity:4];
    FWColorIconView* progressIcon = [[[FWColorIconView alloc] initWithFrame:CGRectMake(0, 0,  16, 16)] autorelease];
    progressIcon.icon = [PIIntegration iconPathForAction:task.action application:application];
    if (progressIcon.icon) {
        [progressSect addObject:
         [[FWDetailListEntry entryWithLocalisedTitle:@"Detail/Action"
                                      localisedValue:[PIIntegration nameForAction:task.action]
                                              bundle:bundle]
          withAccessoryView:progressIcon]];
    }
    
    NSString* importance = localize(bundle, [PIIntegration nameForImportance:task.importance]);
    if ([task.priority length] > 0) {
        NSString* priority = [NSString stringWithFormat:@"%@\n%@", task.priority, task.importance];
        NSString* title = [NSString stringWithFormat:@"%@\n%@",
                           localize(bundle, @"Detail/Priority"),
                           localize(bundle, @"Detail/Importance")];
        
        [progressSect addObject:
         [[FWDetailListEntry entryWithTitle:title
                                      value:priority]
          withLines:2]];
    }
    else {
        [progressSect addObject:
         [FWDetailListEntry entryWithLocalisedTitle:@"Detail/Importance"
                                              value:importance
                                             bundle:bundle]];
    }
    
    [progressSect addObject:
     [[FWDetailListEntry entryWithTitle:[NSString stringWithFormat:localize(bundle, @"Detail/Complete"), task.percentComplete]
                                  value:[NSNumber numberWithFloat:(task.percentComplete / 100.0)]]
      withProgressType]];
    
    
    // Notes section
    NSMutableArray* notesSect = [NSMutableArray arrayWithCapacity:2];
    if (NSString* notes = task.notesSummary) {
        if (notes.length != task.notes.length) {
            [notesSect addObject:
             [[[FWDetailListEntry entryWithTitle:notes]
               withSize:[UIFont systemFontSize]]
              withNoBold]];
            [notesSect addObject:
             [[[FWDetailListEntry entryWithLocalisedTitle:@"Detail/Show Notes"
#ifdef DEVELOPMENT_MODE
                                                    value:kNotesPageDetail
#endif
                                                   bundle:bundle]
               withIconFile:[bundle pathForResource:@"notes" ofType:@"png"]]
              withLinkType:kNotesPageDetail]];
        }
        else {
            [notesSect addObject:
             [[[FWDetailListEntry entryWithTitle:notes]
               withSize:[UIFont systemFontSize]]
              withNoBold]];
        }
    }    
    
    
    // Children/parent section
    FWDetailListSection* relationsSect = nil;
    if (task.isParent) {
        // Fetch child elements
        NSArray* children = [PITaskIntegration basicTaskList:application prefs:nil key:nil parentKey:task.key];
        if ([children count] > 0) {
            NSMutableArray* childs = [NSMutableArray arrayWithCapacity:children.count];
            for (PITask* child in children) {
                [childs addObject:[[[self flaggedEntryWithTitle:child.title
                                                           icon:child.icon
                                                   calendarIcon:child.calendarIcon
                                                        flagged:child.flagged
                                                      largeFlag:NO
                                                    application:application]
#ifdef DEBUG_STATUS
                                    withValue:child.key]
#else
                                   withValue:nil]
#endif
                                   withLinkType:child.key]];
            }
            relationsSect = [FWDetailListSection sectionForElements:childs withTitle:localize(bundle, @"Detail/Children")];
        }
    }
    else if (task.isChild && task.parentKey) {
        // Fetch parent element
        NSArray* parents = [PITaskIntegration basicTaskList:application prefs:nil key:task.parentKey parentKey:nil];
        if ([parents count] > 0) {
            PITask* parent = [parents objectAtIndex:0];
            FWDetailListEntry* link = [[[self flaggedEntryWithTitle:parent.title
                                                               icon:parent.icon
                                                       calendarIcon:parent.calendarIcon
                                                            flagged:parent.flagged
                                                          largeFlag:NO
                                                        application:application]
#ifdef DEBUG_STATUS
                                        withValue:parent.key]
#else
                                       withValue:nil]
#endif
                                       withLinkType:parent.key];
            relationsSect = [FWDetailListSection sectionForElements:[NSArray arrayWithObject:link] 
                                                          withTitle:localize(bundle, @"Detail/Parent")];
        }
    }
    
    // Build sections list
    NSMutableArray* sects = [NSMutableArray arrayWithCapacity:6];
    [sects addObject:[FWDetailListSection sectionForElements:titleSect]];
    if ([datesSect count] > 0)
        [sects addObject:[FWDetailListSection sectionForElements:datesSect]];
    if ([progressSect count] > 0)
        [sects addObject:[FWDetailListSection sectionForElements:progressSect]];
    if ([contextSect count] > 0)
        [sects addObject:[FWDetailListSection sectionForElements:contextSect]];
    if (relationsSect)
        [sects addObject:relationsSect];
    if ([notesSect count] > 0)
        [sects addObject:[FWDetailListSection sectionForElements:notesSect
                                                       withTitle:localize(bundle, @"Detail/Notes")]];
    //DebugLog(@"LI:PITodo: Detail read = %@", sects);
    
    if (parentKeys) {
        for (FWDetailListSection* sect in sects) {
            for (FWDetailListEntry* element in sect.entries) {
                if (element.isLink) {
                    for (NSString* key in parentKeys) {
                        if ([element.key isEqualToString:key]) {
                            element.link = NO;
                            element.backLink = YES;
                            break;
                        }
                    }
                }
            }
        }
    }
    
    return sects;
}

- (NSArray*)dataForDetailListPage:(NSObject*)page key:(NSObject*)key application:(FWApplication *)application
{
    if (key && [(NSString*)key isEqualToString:kTagsPageLookup])
        return [self dataForTagsListPage:page application:application];
    else
        return [self dataForTaskListPage:page application:application];
}

- (void)willShowBasePage:(NSObject*)page
{
    self.parentKeys = nil;
    self.detailPageID = nil;
}

- (NSString*)listPageTextForKey:(NSObject *)key currentPage:(NSObject *)page displayDepth:(NSInteger)depth application:(FWApplication *)application
{
    if ([(NSString*)key isEqualToString:kNotesPageDetail]) {
        PITask* task = [PITaskIntegration augmentedBasicTask:(PITask*)page application:application];
        if (task.notes)
            return task.notes;
        else
            return @"";
    }
    
    return nil;
}

- (NSArray*)listPageInfoForKey:(NSObject*)key currentPage:(NSObject*)current displayDepth:(NSInteger)depth application:(FWApplication *)application
{
    self.detailPageID = (NSString*)key;
    
    if ([(NSString*)key isEqualToString:kTagsPageLookup])
        return [NSArray arrayWithObject:current];

    if (depth >= 1) {
        if (!parentKeys)
            self.parentKeys = [NSMutableArray arrayWithCapacity:3];

        while (parentKeys.count >= depth)
            [parentKeys removeLastObject];

         [parentKeys addObject:((PITask*)current).key];
    }
    
    return [PITaskIntegration basicTaskList:application prefs:nil key:(NSString*)key parentKey:nil];
}

@end
